package utils

import (
	"errors"
	"time"

	"github.com/dgrijalva/jwt-go"
)

var MySecret = []byte("pspklemf*232(dsowl22fs656hd卡")

const TokenExpireDuration = time.Hour * 240
const RefreshTokenExpireDuration = TokenExpireDuration * 10000

type MyClaims struct {
	User map[string]interface{} `json:"user"`
	jwt.StandardClaims
}
type RefreshClaims struct {
	UID string `json:"userid"`
	jwt.StandardClaims
}

//生成token和refreshtoken
func GenToken(user map[string]interface{}) (string, string, error) {
	// 创建一个我们自己的声明
	c := MyClaims{
		user, // 自定义字段
		jwt.StandardClaims{
			ExpiresAt: time.Now().Add(TokenExpireDuration).Unix(), // 过期时间
			Issuer:    "funlog",                                   // 签发人
		},
	}
	c1 := RefreshClaims{
		Strval(user["id"]), // 自定义字段
		jwt.StandardClaims{
			ExpiresAt: time.Now().Add(TokenExpireDuration).Unix(), // 过期时间
			Issuer:    "funlog",                                   // 签发人
		},
	}
	// 使用指定的签名方法创建签名对象
	tokenG := jwt.NewWithClaims(jwt.SigningMethodHS256, c)
	// 使用指定的签名方法创建签名对象
	refreshToenG := jwt.NewWithClaims(jwt.SigningMethodHS256, c1)
	token, err1 := tokenG.SignedString(MySecret)
	refreshToen, err2 := refreshToenG.SignedString(MySecret)
	var err error
	if err1 != nil {
		err = err1
	} else if err2 != nil {
		err = err2
	}
	// 使用指定的secret签名并获得完整的编码后的字符串token
	return token, refreshToen, err
}

func ParseToken(tokenString string) (*MyClaims, error) {
	// 解析token
	token, err := jwt.ParseWithClaims(tokenString, &MyClaims{}, func(token *jwt.Token) (i interface{}, err error) {
		return MySecret, nil
	})
	if err != nil {
		return nil, err
	}
	if claims, ok := token.Claims.(*MyClaims); ok && token.Valid { // 校验token
		return claims, nil
	}
	return nil, errors.New("invalid token")
}

func ParseReToken(tokenString string) (*RefreshClaims, error) {
	// 解析token
	token, err := jwt.ParseWithClaims(tokenString, &RefreshClaims{}, func(token *jwt.Token) (i interface{}, err error) {
		return MySecret, nil
	})
	if err != nil {
		return nil, err
	}
	if claims, ok := token.Claims.(*RefreshClaims); ok && token.Valid { // 校验token
		return claims, nil
	}
	return nil, errors.New("invalid token")
}
